<template>
  <div>
    <div class="design-header">
      <div class="design-header__title">
        <div class="design-header__title-circle"></div>
        <div class="design-header__title-label">设计需求表</div>
      </div>
      <div class="design-header__buttons">
        <div class="button-item" @click="handelPreview">
          <el-icon><View /></el-icon>
          <div class="button-label">表单预览</div>
        </div>
        <div class="button-item save-button" @click="handelSaveForm">
          <el-icon><Download /></el-icon>
          <div class="button-label">保存</div>
        </div>
      </div>
    </div>
    <el-container class="design-form">
      <el-aside style="width: 250px">
        <!--    分组  start  -->
        <div class="form-group">
          <div class="form-group__header">
            <div class="title">分组</div>
            <el-button type="primary" link :icon="Plus" @click="addGroup">添加分组</el-button>
          </div>
          <div class="form-group__list" v-loading="isLoadingGroup">
            <template v-if="groups.length">
              <VueDraggableNext
                v-model="groups"
                group="from"
                handle=".sort"
                animation="300"
                @start="groupStartSort"
                @end="groupEndSort"
              >
                <div
                  class="list-item"
                  :class="{ 'list-item--active': item.formId === currentGroupItem?.formId }"
                  v-for="(item, index) in groups"
                  :key="item.formId"
                >
                  <template v-if="item.isOpera">
                    <div class="list-item__label" style="margin-right: 10px">
                      <el-input v-model="catchCurrentGroup.formName" v-autoFocus placeholder="请输入分组名称" />
                    </div>
                    <div class="list-item__operate">
                      <svg-icon icon-class="submit-icon" @click="handelSaveGroup(item, index)" />
                      <svg-icon icon-class="del-icon" @click="handelDelGroup(item, index)" />
                    </div>
                  </template>
                  <template v-else>
                    <div class="list-item__label" @click.stop="changeGroup(item, index)">{{ item.formName }}</div>
                    <div class="list-item__operate list-item__operate--hover">
                      <template v-if="item.isOperable">
                        <svg-icon icon-class="edit-icon" v-if="!item.isOpera" @click="handelEditGroup(item, index)" />
                        <svg-icon icon-class="submit-icon" v-else @click="handelSaveGroup(item, index)" />
                        <svg-icon icon-class="del-icon" @click="handelDelGroup(item, index)" />
                      </template>
                      <svg-icon icon-class="vertical-drag" class="sort" />
                    </div>
                  </template>
                </div>
              </VueDraggableNext>
            </template>
            <el-empty v-else />
          </div>
        </div>
        <!--   分组  end   -->
        <!--    组件列表 start  -->
        <div class="components-list">
          <div class="title">组件库</div>
          <ul>
            <VueDraggableNext
              class="drag"
              :list="baseCps"
              :sort="false"
              :group="{ name: 'form', pull: 'clone', put: false }"
              @start="isStart = true"
              @end="isStart = false"
              :clone="clone"
            >
              <li v-for="(cp, id) in baseCps" :key="id">
                <el-icon>
                  <component :is="cp.icon"></component>
                </el-icon>
                <span>{{ cp.title }}</span>
              </li>
            </VueDraggableNext>
          </ul>
        </div>
        <!--    组件列表 end  -->
      </el-aside>
      <template v-if="currentGroupItem?.formId">
        <ElectricalEquipment v-if="currentGroupItem?.formId === electricalEquipment" />
        <template v-else>
          <el-main class="layout-main">
            <div class="tool-nav">
              <div></div>
              <div class="option-buttons">
                <div class="linkage-button">
                  <el-dropdown placement="bottom" trigger="click">
                    <div class="copy-btn">
                      <el-icon size="14px" color="#007DFF"><CopyDocument /></el-icon>
                      复制其他分组
                    </div>
                    <template #dropdown>
                      <el-dropdown-menu :teleported="false">
                        <el-dropdown-item
                          v-for="(item, index) in copyGroupsList"
                          :key="`${item.formId}`"
                          @click="copyGroup(item)"
                        >
                          <div class="dropdown-item">
                            <div class="dropdown-item__text">
                              <ellipsis :row="1" hover-tip :content="item.formName" />
                            </div>
                            <el-icon size="14px" color="#007DFF" style="margin-right: 5px"><CopyDocument /></el-icon>
                          </div>
                        </el-dropdown-item>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                </div>
                <div class="linkage-button" @click="handelShowFormLinkage">
                  <el-icon><List /></el-icon>
                  联动规则
                </div>
              </div>
            </div>
            <div class="work-form">
              <div :class="{ mobile: showMobile, pc: !showMobile }">
                <div :class="{ bd: showMobile }">
                  <div :class="{ 'form-content': showMobile }">
                    <div class="form">
                      <div class="tip" v-if="forms.length === 0 && !isStart">请在左侧选择控件并拖至此处</div>
                      <VueDraggableNext
                        v-else
                        class="drag-from"
                        :list="forms"
                        group="form"
                        :animation="300"
                        chosen-class="choose"
                        @start="
                          drag = true;
                          selectFormItem = null;
                        "
                        @end="drag = false"
                      >
                        <div
                          v-for="(cp, id) in forms"
                          :key="id"
                          class="form-item"
                          @click="selectItem(cp)"
                          :style="getSelectedClass(cp)"
                        >
                          <div class="form-header">
                            <p><span v-if="cp.props.required">*</span>{{ cp.title }}</p>
                            <div class="option">
                              <svg-icon icon-class="del-icon" @click="del(id)" />
                            </div>
                            <form-design-render :config="cp" />
                          </div>
                        </div>
                      </VueDraggableNext>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </el-main>

          <el-aside class="layout-param">
            <div v-if="!selectFormItem || forms.length === 0">
              <form-config />
            </div>
            <template v-else>
              <div>组件设置</div>
              <el-radio-group v-model="setItem" style="margin: 10px 0 10px 10px">
                <el-radio-button label="基础属性" value="1" />
                <el-radio-button label="图文案例" value="2" />
                <el-radio-button label="优劣势对比" value="3" />
              </el-radio-group>
              <div style="text-align: left; padding: 10px">
                <form-component-config v-if="setItem === '1'" />
                <image-text-config v-if="setItem === '2'" />
                <compare-config v-if="setItem === '3'" />
              </div>
            </template>
          </el-aside>
        </template>
      </template>
      <el-empty description="请选择分组" v-else />
    </el-container>

    <!-- 表单预览 -->
    <w-dialog
      clickClose
      width="1200px"
      :click-close="false"
      closeFree
      :showFooter="false"
      :border="false"
      @close="handelClosePreview"
      title="设计需求调研表"
      v-model="viewVisible"
    >
      <div class="preview" v-if="viewVisible">
        <div class="preview__groups">
          <div
            class="preview__groups__item"
            :class="{ 'preview__groups__item--active': item.formId === currentPreviewGroupItem?.formId }"
            v-for="(item, index) in groups"
            :key="item.formId"
            @click="handelPreviewGroup(item, index)"
          >
            <span>{{ item.formName }}</span>
          </div>
        </div>
        <div class="preview__forms" v-loading="isLoadingPreview">
          <ElectricalEquipmentPreview
            :data="electricalEquipmentTable"
            v-if="currentPreviewGroupItem?.formId === electricalEquipment"
          />

          <form-render
            v-else-if="previewFormItems.length"
            ref="form"
            :forms="previewFormItems"
            mode="PC"
            :config="previewFormConfig"
            v-model="formData"
          />
          <el-empty v-else />
        </div>
      </div>
    </w-dialog>
  </div>
</template>

<script setup>
import { computed, ref, getCurrentInstance, watch } from "vue";
import { Plus, View, List, CopyDocument, Download } from "@element-plus/icons-vue";
import { cloneDeep } from "lodash";
import { VueDraggableNext } from "vue-draggable-next";
import useFlowStore from "@/store/modules/gkflow.js";
import { baseComponents } from "./config/ComponentsConfigExport.js";
import FormDesignRender from "./components/FormDesignRender.vue";
import FormComponentConfig from "./config/FormComponentConfig";
import ImageTextConfig from "./config/ImageTextConfig.vue";
import CompareConfig from "./config/CompareConfig.vue";
import ElectricalEquipment from "./ElectricalEquipment.vue";
import ElectricalEquipmentPreview from "@/views/system/designForm/components/ElectricalEquipmentPreview.vue";
import FormConfig from "./config/FormConfig.vue";
import FormRender from "./components/FormRender.vue";
import { getId, parseOrDefault } from "@/utils";
import * as requestApis from "@/api/designForm";
import { formItemsByFormId } from "@/api/designForm";

const { proxy } = getCurrentInstance();
const flowStore = useFlowStore();

/**
 * 分组列表
 */
const isLoadingGroup = ref(false);
const electricalEquipment = "form-6687c10660b2252520caa5fg";
const groups = ref([]);
const getGroupList = async () => {
  try {
    isLoadingGroup.value = true;
    const { data } = await requestApis.formGroupList();
    groups.value = data || [];
    isLoadingGroup.value = false;
  } catch (err) {
    isLoadingGroup.value = false;
    console.log(err);
  }
};
const isHasAddItem = () => {
  return groups.value.some(item => item.isOpera);
};
const catchCurrentGroup = ref({
  formId: "",
  formName: ""
});
const addGroup = () => {
  if (isHasAddItem()) {
    return proxy.$modal.msgError("您还有未完成的操作");
  }
  groups.value.push({
    formId: "",
    formName: "",
    isOpera: true
  });
};
const handelEditGroup = (data, index) => {
  data.isOpera = true;
  catchCurrentGroup.value = cloneDeep(data);
};
const handelSaveGroup = async () => {
  if (!catchCurrentGroup.value.formName) return proxy.$modal.msgError("请填写分组名称");
  const isHasSameName = groups.value.filter(item => item.formName === catchCurrentGroup.value.formName);
  if (isHasSameName?.length >= 2) {
    if (catchCurrentGroup.value.formId) {
      catchCurrentGroup.value.formName = "";
    } else {
      catchCurrentGroup.value.formId = "";
      catchCurrentGroup.value.formName = "";
    }
    return proxy.$modal.msgError("分组名称不能重复");
  }
  try {
    isLoadingGroup.value = true;
    const postData = {
      formId: catchCurrentGroup.value.formId,
      formName: catchCurrentGroup.value.formName
    };
    postData.formId = catchCurrentGroup.value.formId || getId("form-");
    await requestApis[catchCurrentGroup.value.formId ? "editGroup" : "addGroup"](postData);
    isLoadingGroup.value = false;
    catchCurrentGroup.value = {
      formId: "",
      formName: ""
    };
    getGroupList();
    proxy.$modal.msgSuccess("保存成功");
  } catch (err) {
    isLoadingGroup.value = false;
    console.log(err);
  }
};
const handelDelGroup = async (item, index) => {
  if (item.isOpera && !item.formId) {
    return groups.value.splice(index, 1);
  }
  const tipMessage = `您正在删除【${item.formName}】分组，同时会删除该分组下已设置的表单，请确认是否删除？`;
  proxy.$modal.confirm(tipMessage).then(async () => {
    try {
      isLoadingGroup.value = true;
      await requestApis.deleteGroup(item.formId);
      groups.value.splice(index, 1);
      if (currentGroupItem.value.formId === item.formId) {
        currentGroupItem.value = null;
      }
      isLoadingGroup.value = false;
      proxy.$modal.msgSuccess("删除成功");
    } catch (err) {
      isLoadingGroup.value = false;
      console.log(err);
    }
  });
};

/**
 * 分组排序
 */
const sortCloneGroups = ref([]);
const groupStartSort = () => {
  sortCloneGroups.value = cloneDeep(groups.value);
};
const groupEndSort = async () => {
  try {
    await requestApis.sortGroup(groups.value);
  } catch (err) {
    groups.value = cloneDeep(sortCloneGroups.value);
    console.log(err);
  }
};

/**
 * 选择分组
 */
const currentGroupItem = ref(null);
const isLoadingForm = ref(false);
const changeGroup = async (item, index) => {
  try {
    isLoadingForm.value = true;
    currentGroupItem.value = cloneDeep(item);
    const { data } = await requestApis.formItemsByFormId(item.formId);
    const formItemData = data?.length ? data[0] : {};
    const formConfig = parseOrDefault(formItemData.props, { formConfig: {}, formItems: [], formDataObj: {} });
    if (item.formId === electricalEquipment) {
      if (formConfig?.formItems?.length) {
        flowStore.equipmentList = formConfig.formItems[0]?.props?.options?.length ? formConfig.formItems[0]?.props?.options : [];
      }
      return (isLoadingForm.value = false);
    }
    flowStore.design = formConfig;
    flowStore.selectFormItem = null;
    setItem.value = "1";
    isLoadingForm.value = false;
  } catch (err) {
    isLoadingForm.value = false;
    console.log(err);
  }
};

/**
 * 复制分组
 */
const copyGroupsList = computed(() => {
  const list = cloneDeep(groups.value);
  const removeIndex = list.findIndex(item => item.formId === electricalEquipment);
  list.splice(removeIndex, 1);
  return list;
});
const copyGroup = async item => {
  try {
    isLoadingForm.value = true;
    const { data } = await requestApis.formItemsByFormId(item.formId);
    const formItemData = data?.length ? data[0] : {};
    flowStore.design = parseOrDefault(formItemData.props, { formConfig: {}, formItems: [] });
    proxy.$modal.msgSuccess("复制成功");
    isLoadingForm.value = false;
  } catch (err) {
    isLoadingForm.value = false;
    console.log(err);
  }
};

const setItem = ref("1");
const isStart = ref(false);
const baseCps = ref(baseComponents);
const clone = obj => {
  obj.id = getId();
  return cloneDeep(obj);
};
const showMobile = ref(false);
const drag = ref(false);
const design = computed(() => {
  return flowStore?.design || {};
});
const forms = computed(() => {
  return flowStore.design?.formItems;
});
const formConfig = computed(() => {
  return design.value?.formConfig || {};
});
const selectFormItem = computed({
  get: () => flowStore.selectFormItem,
  set: val => {
    flowStore.selectFormItem = val;
  }
});
const nodeMap = computed(() => {
  return flowStore.nodeMap;
});
const selectItem = cp => {
  selectFormItem.value = cp;
};
const getSelectedClass = cp => {
  return selectFormItem.value && selectFormItem.value.id === cp.id ? "border-left: 4px solid #409eff" : "";
};

const handelShowFormLinkage = () => {
  selectFormItem.value = null;
};
const del = index => {
  proxy.$modal
    .confirm("删除组件将会连带删除包含该组件的条件以及相关设置，是否继续?")
    .then(() => {
      removeFormItemAbout(forms.value[index]);
      forms.value.splice(index, 1);
      flowStore.selectFormItem = null;
    })
    .catch(() => {});
};
const removeFormItemAbout = async item => {
  nodeMap.value.forEach(node => {
    if (node.type === "CONDITION") {
      node.props.groups.forEach(group => {
        let i = group.cids.remove(item.id);
        if (i > -1) {
          group.conditions.splice(i, 1);
        }
      });
    }
    if (node.type === "ROOT" || node.type === "APPROVAL" || node.type === "CC") {
      node.props.formPerms.removeByKey("id", item.id);
      if (node.props.formUser === item.id) {
        node.props.formUser = "";
      }
    }
  });
};

/**
 * 保存设置
 */
let postConfig;
const hasDuplicateNames = items => {
  const nameSet = new Set();
  for (const item of items) {
    if (nameSet.has(item.label)) {
      return true;
    }
    nameSet.add(item.label);
  }
  return false;
};

const handelSaveForm = async () => {
  if (currentGroupItem.value.formId === electricalEquipment) {
    const isHasEmpty = flowStore.equipmentList.some(item => !item.label);
    if (isHasEmpty) return proxy.$modal.msgError("请完善家用电器记录表");
    if (hasDuplicateNames(flowStore.equipmentList)) return proxy.$modal.msgError("家用电器类别名称不允许重复");
    postConfig = {
      formItems: [
        {
          id: getId(),
          name: "SelectTable",
          title: "家用电器记录表",
          props: {
            options: flowStore.equipmentList
          }
        }
      ]
    };
  } else {
    const formItems = cloneDeep(flowStore.design?.formItems ?? []);
    const isHasTitleEmpty = formItems.some(item => {
      if (!item.title) {
        return true;
      }
    });
    if (isHasTitleEmpty) return proxy.$modal.msgError("请填写表单组件名称");
    const titles = formItems.map(item => item.title);
    const isSameName = [...new Set(titles)].length === titles.length;
    if (!isSameName) return proxy.$modal.msgError("表单组件名称不允许重复");
    postConfig = flowStore.design;
  }
  try {
    const postData = {
      formId: currentGroupItem.value.formId,
      props: JSON.stringify(postConfig)
    };
    await requestApis.addFormTemplate(postData);
    getGroupList();
    proxy.$modal.msgSuccess("保存成功");
  } catch (err) {
    console.log(err);
  }
};

/**
 * 预览
 */
const viewVisible = ref(false);
const currentPreviewGroupItem = ref({});
const handelPreview = () => {
  viewVisible.value = true;
};
const formData = ref({});
const previewFormItems = ref([]);
const previewFormConfig = ref({});
const electricalEquipmentTable = ref([]);
const isLoadingPreview = ref(false);
const handelPreviewGroup = async (item, index) => {
  try {
    isLoadingPreview.value = true;
    currentPreviewGroupItem.value = cloneDeep(item);
    const { data } = await requestApis.formItemsByFormId(item.formId);
    const formItemData = data?.length ? data[0] : {};
    const design = parseOrDefault(formItemData.props, { formConfig: {}, formItems: [], formDataObj: {} });
    if (item.formId === electricalEquipment) {
      if (design?.formItems?.length) {
        electricalEquipmentTable.value = design?.formItems[0]?.props?.options?.length ? design.formItems[0].props.options : [];
      }
      isLoadingPreview.value = false;
      return;
    }
    previewFormItems.value = design.formItems;
    previewFormConfig.value = design.formConfig;
    formData.value = {};
    isLoadingPreview.value = false;
  } catch (err) {
    isLoadingPreview.value = false;
    console.log(err);
  }
};
const handelClosePreview = () => {
  viewVisible.value = false;
  currentPreviewGroupItem.value = {};
  electricalEquipmentTable.value = [];
  previewFormItems.value = [];
  previewFormConfig.value = {};
  formData.value = [];
};

getGroupList();
</script>

<style scoped lang="scss">
@import "designForm";
</style>
